#include "MeshLabel.hpp"

using namespace Typhoon;

MeshLabel::MeshLabel() : 
	Font(this),
	FontSize(this),
	Text(this),
	HAlignment(this),
	VAlignment(this),
	Size(this),
	TextureCoords(this),
	Color(this),
	WordWrap(this)
{
	Size = 0;
	Size.Changed += event_handler(this, &MeshLabel::TextChanged);
	Font = 0;
	Font.Changed+=event_handler(this, &MeshLabel::TextChanged);
	Text = "";
	Text.Changed+=event_handler(this, &MeshLabel::TextChanged);
	FontSize = 1;
	FontSize.Changed+=event_handler(this, &MeshLabel::TextChanged);
	textIsDirty = false;
    TextureCoords = Box(0,0,1,1);
	HAlignment = TextFont::Left;
	VAlignment = TextFont::Top;
	HAlignment.Changed+=event_handler(this, &MeshLabel::TextChanged);
	VAlignment.Changed+=event_handler(this, &MeshLabel::TextChanged);
	Color = Colour::White();
	WordWrap = false;
	WordWrap.Changed+=event_handler(this, &MeshLabel::TextChanged);
}

MeshLabel::~MeshLabel() {
    
}

void MeshLabel::Visualize() {
	
	int indicesIndex = 0;
	int verticesIndex = 0;

	vertices.resize(letters.size() * 4);
	triangles.resize(letters.size() * 6);

	for (int i=0; i<letters.size(); i++) {

		triangles[indicesIndex++] = (GLshort)(verticesIndex);
		triangles[indicesIndex++] = (GLshort)(verticesIndex+2);
		triangles[indicesIndex++] = (GLshort)(verticesIndex+1);
		triangles[indicesIndex++] = (GLshort)(verticesIndex);
		triangles[indicesIndex++] = (GLshort)(verticesIndex+3);
		triangles[indicesIndex++] = (GLshort)(verticesIndex+2);

		int index = verticesIndex;

		Vertex& v0 = vertices[index + 0];
		Vertex& v1 = vertices[index + 1];
		Vertex& v2 = vertices[index + 2];
		Vertex& v3 = vertices[index + 3];
        
        /*
        vertices.push_back(mat->TransformPoint(Vector2(letters[i].x, letters[i].y)));
		vertices.push_back(mat->TransformPoint(Vector2(letters[i].x+letters[i].width, letters[i].y)));
		vertices.push_back(mat->TransformPoint(Vector2(letters[i].x+letters[i].width, letters[i].y+letters[i].height)));
		vertices.push_back(mat->TransformPoint(Vector2(letters[i].x, letters[i].y+letters[i].height)));
		
        textureCoords.push_back(Vector2(letters[i].u1, letters[i].v2));
        textureCoords.push_back(Vector2(letters[i].u2, letters[i].v2));
        textureCoords.push_back(Vector2(letters[i].u2, letters[i].v1));
        textureCoords.push_back(Vector2(letters[i].u1, letters[i].v1));
        */

		v0.Position = Vector2(letters[i].x, letters[i].y);
		v1.Position = Vector2(letters[i].x+letters[i].width, letters[i].y);
		v2.Position = Vector2(letters[i].x+letters[i].width, letters[i].y+letters[i].height);
		v3.Position = Vector2(letters[i].x, letters[i].y+letters[i].height);
		
        
		v0.TextureCoords.x = letters[i].u1;
		v0.TextureCoords.y = letters[i].v2;
		
		v1.TextureCoords.x = letters[i].u2;
		v1.TextureCoords.y = letters[i].v2;

		v2.TextureCoords.x = letters[i].u2;
		v2.TextureCoords.y = letters[i].v1;

		v3.TextureCoords.x = letters[i].u1;
		v3.TextureCoords.y = letters[i].v1;
        
        
        /*
        v0.TextureCoords.x = letters[i].u1;
		v0.TextureCoords.y = letters[i].v1;
		
		v1.TextureCoords.x = letters[i].u2;
		v1.TextureCoords.y = letters[i].v1;
        
		v2.TextureCoords.x = letters[i].u2;
		v2.TextureCoords.y = letters[i].v2;
        
		v3.TextureCoords.x = letters[i].u1;
		v3.TextureCoords.y = letters[i].v2;
        */

		const Colour color = Color.GetValue();

		v0.Color = color;
		v1.Color = color;
		v2.Color = color;
		v3.Color = color;

		verticesIndex += 4;
	}
}

const Mesh::VerticesList& MeshLabel::ReadOnlyVertices() {
	if (textIsDirty) {
		textIsDirty = false;
		CreateText();
		Visualize();
		BoundingBox.MakeDirty();
	}
	return vertices;
}

const Mesh::TrianglesList& MeshLabel::ReadOnlyTriangles()
{
	return triangles;
}

void MeshLabel::TextChanged(MeshLabel* label) {
	textIsDirty = true;
}

void MeshLabel::CreateText() {
	if (!Font()) {
		return;
	}
	letters.clear();
	Font()->CreateText(&letters, Text, Size, FontSize, HAlignment, VAlignment, WordWrap);

	Box t = TextureCoords();
	float w = t.right - t.left;
	float h = t.bottom - t.top;

	for (int i=0; i<letters.size(); i++) {
		letters[i].u1 = t.left + letters[i].u1 * w;
		letters[i].u2 = t.left + letters[i].u2 * w;
		letters[i].v1 = t.top + letters[i].v1 * h;
		letters[i].v2 = t.top + letters[i].v2 * h;
	}
    
        
       
    
}